package com.xxjh.brs.mapresources.controller;

import com.xxjh.brs.ftp.common.api.enums.ResponseStatus;
import com.xxjh.brs.ftp.common.exceptions.ConditionException;
import com.xxjh.brs.map.dto.ImageFile;
import com.xxjh.brs.map.dto.MapTileParam;
import com.xxjh.brs.map.dto.RangeParam;
import com.xxjh.brs.map.utils.MapDownLoadConstants;
import com.xxjh.brs.map.utils.TileCoordinateConverter;
import com.xxjh.brs.map.vo.DownloadProgress;
import com.xxjh.brs.map.vo.DownloadTask;
import com.xxjh.brs.map.vo.EstimateData;
import com.xxjh.brs.mapresources.service.MapDownloadService;
import com.xxjh.brs.mvc.annotation.IgnoreResponseAdvice;
import com.xxjh.brs.mvc.annotation.SkipLogging;
import com.xxjh.brs.mvc.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.io.File;
import java.io.IOException;

import static com.xxjh.brs.map.utils.MapDownLoadConstants.IMG_SIZE;

/**
 * @author CHENCHEN
 * @title 地图资源下载器
 * @company 新兴际华科技（天津）有限公司
 * @create 2024-05-31 9:28
 */
@Slf4j
@Api(value = "地图资源下载器")
@RestController
public class MapDownloadController extends BaseController {

    @Autowired
    private MapDownloadService mapDownloadService;

    /**
     * @description: 根据经纬度范围下载地图瓦片
     * @param: mapParam [extent数组类型左下右上顺序，minHeight最小层级，maxHeight最大层级，alias为地图类型影像图或矢量图]
     * @return: DownloadTask
     * @date: 2024/6/11 9:36
     * @Author: CHENCHEN
     */
    @ApiOperation(value = "范围下载", notes = "传入经纬度范围与从第几层下载")
    @ApiResponse(code = 200, message = "成功", response = DownloadTask.class)
    @PostMapping("/download")
    public DownloadTask  downloadFile(@RequestBody RangeParam rangeParam) {
        if(rangeParam.maxHeight <= 20){
            return mapDownloadService.startDownloadTiles(rangeParam);
        }
        throw new ConditionException(ResponseStatus.FORBIDDEN);
    }

    /**
     * @description: 资源库不存在时下载地图瓦片
     * @param: mapTileParam[x, y, z, alias] [x最下层, y中间层, z最大层, alias为地图类型影像图或矢量图]
     * @return: org.springframework.http.ResponseEntity<org.springframework.core.io.FileSystemResource>
     * @date: 2024/6/13 9:38
     * @Author: CHENCHEN
     */
    @IgnoreResponseAdvice
    @ApiIgnore
    @GetMapping("/downloadTile")
    @SkipLogging
    public ResponseEntity<FileSystemResource> downloadFile(MapTileParam mapTileParam) throws IOException {
        ImageFile imageFile = mapDownloadService.downloadMapTile(mapTileParam);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);
        headers.setContentLength(imageFile.getImageLength());
        return ResponseEntity.ok()
                .headers(headers)
                .body(new FileSystemResource(new File(imageFile.getLocalPath())));
    }

    /**
     * @description: 预估下载任务大小
     * @param: [mapParam] [extent数组类型左下右上顺序，minHeight最小层级，maxHeight最大层级，alias为地图类型影像图或矢量图]
     * @return: EstimateData
     * @date: 2024/6/17 19:41
     * @Author: CHENCHEN
     */
    @ApiOperation(value = "预估下载任务", notes = "传入经纬度范围与从第几层下载")
    @ApiResponse(code = 200, message = "成功", response = EstimateData.class)
    @PostMapping("/download/estimate")
    public EstimateData estimateDownloadInfo(@RequestBody RangeParam rangeParam) {
        if(rangeParam.maxHeight <= 20){
            int totalTiles = MapDownLoadConstants.calculateTotalTiles(rangeParam.getExtent(), rangeParam.getMinHeight(),
                    rangeParam.getMaxHeight());
            return new EstimateData(
                    totalTiles, TileCoordinateConverter.
                    convertBytesToAppropriateUnit(totalTiles * IMG_SIZE)
            );
        }
        throw new ConditionException(ResponseStatus.FORBIDDEN);
    }

    /**
     * @description: 获取当前下载进度信息。
     * @param: [taskId] 任务ID
     * @return: DownloadProgress
     * @date: 2024/6/18 20:11
     * @Author: CHENCHEN
     */
    @ApiOperation(value = "获取当前下载进度信息", notes = "传入downloadTile接口返回的taskId")
    @ApiResponse(code = 200, message = "成功", response = DownloadProgress.class)
    @GetMapping("/{taskId}/progress")
    public DownloadProgress getDownloadProgress(
            @ApiParam(value = "下载任务的唯一标识符", required = true, example = "112636209862606848/progress")
            @PathVariable Long taskId) {
        return mapDownloadService.getDownloadProgress(taskId);
    }
}
